"""
几何相关的计算函数
"""
import numpy as np

def identity_mat4()->np.ndarray:
    """
    返回一个4x4单位矩阵
    """
    mat4 = np.zeros((4,4),dtype=np.float64)
    for i in range(4):
        mat4[i,i] = 1.
    return mat4

def rotate_mat4(c:float,s:float,x:float,y:float,z:float)->np.ndarray:
    """
    构造一个4x4旋转矩阵
    c = cos(a)
    s = sin(a)
    """
    m = identity_mat4()
    m[0,0] = x*x*(1-c)+c
    m[0,1] = x*y*(1-c)-z*s
    m[0,2] = x*z*(1-c)+y*s
    m[1,0] = y*x*(1-c)+z*s
    m[1,1] = y*y*(1-c)+c
    m[1,2] = y*z*(1-c)-x*s
    m[2,0] = x*z*(1-c)-y*s
    m[2,1] = y*z*(1-c)+x*s
    m[2,2] = z*z*(1-c)+c
    return m

def translate_mat4(dx:float,dy:float,dz:float)->np.ndarray:
    """
    构造一个4x4平移矩阵
    """
    m = identity_mat4()
    m[0,3] = dx
    m[1,3] = dy
    m[2,3] = dz
    return m

def normalized(v:np.ndarray)->np.ndarray:
    """
    计算正则化向量
    """
    d = np.sum(v * v)
    return v/np.sqrt(d)

def frustum_mat4(left:float,right:float,
                 bottom:float,top:float,
                 near:float,far:float)->np.ndarray:
    """
    透视矩阵
    """
    m = identity_mat4()
    m[0,0] = 2*near/(right-left)
    m[1,1] = 2*near/(top-bottom)
    m[0,2] = (right+left)/(right-left)
    m[1,2] = (top+bottom)/(top-bottom)
    m[2,2] = -(far+near)/(far-near)
    m[2,3] = -2*far*near/(far-near)
    return m
